package org.dyndns.cooland.indexer;

import java.io.*;
//import java.util.*;
import java.util.zip.*;
import org.dom4j.*;
import org.dom4j.io.*;

public class Main {

	static String working_folder;
	static XMLWriter writer; 
	static FileWriter out;
	static String CATALOG_VERSION="1.0";
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {

		if (args.length<1||args.length>1){
			show_usage();
			System.exit(0);
		}
		working_folder = args[0];

		File f = new File(working_folder);
		if (!f.exists()){
			System.out.println("Directory "+working_folder+" not found");
			System.exit(1);
		}

		if (!f.isDirectory()){
			System.out.println(working_folder+" not a directory");
			System.exit(1);
		}

		//TODO 
		createCatalogFile();
		process_directory(working_folder);
		closeCatalogFile();
		
		compressFile(working_folder+File.separator+"catalog.xml",working_folder+File.separator+"catalog.zip");
		//TODO delete catalog.xml?
	}

	
	private static void createCatalogFile(){
		try{
			out=new FileWriter(working_folder+File.separator+"catalog.xml");
			//OutputFormat format = new OutputFormat("  ", true);
			OutputFormat format = OutputFormat.createCompactFormat();
			format.setEncoding("UTF-8");
			format.setNewlines(true);
			format.setIndentSize(2);
			format.setTrimText(false);
			writer = new XMLWriter(out, format);
		
			out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
			out.write("<catalog version=\""+CATALOG_VERSION+"\">\n");
		}
		catch (Exception e){
			e.printStackTrace();
		}
	}
	
	private static void closeCatalogFile(){
		try{
			out.write("\n</catalog>");
			out.close();
		}
		catch (Exception e){
			e.printStackTrace();
		}
		
	}
	
	public static void saveToCatalog(Element addon){
			try{
			writer.write(addon);
			writer.write("\n");
			}
			catch (Exception e){
				e.printStackTrace();
			}
		
	}
	
	public static void process_xml(File file){

		try{
			ZipFile zf = new ZipFile(file);
			ZipEntry ze = zf.getEntry("info.xml");
			if (ze == null){
				throw new FileNotFoundException ("No info.xml found, skip");
			}

			InputStream is = zf.getInputStream(ze);
			FileInputStream fis = new FileInputStream( file);
			String md5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(fis);
			String path = file.getAbsolutePath().substring(working_folder.length());
		SAXReader reader = new SAXReader();

		Document doc=reader.read(is);
		//TODO add validation of info.xml by info.xsd
		
		Element root=doc.getRootElement();
		
		if (root.getName()=="addon"){
			Element el=root.addElement("download");
			//el.addElement("source").addText(path.replace("\\", "/"));
			el.addElement("source").addText(file.getName());	
			el.addElement("checksum").addText(md5);
			el.addElement("size").addText(Long.toString(file.length()));
			//TODO 
			/*
			Element files = el.addElement("files");
			Enumeration f_enum = zf.entries();
			while(f_enum.hasMoreElements()){
				ZipEntry z_file= (ZipEntry)f_enum.nextElement();
				long f_size=z_file.getSize();
				
				Element e_file=files.addElement("file");
				e_file.addText(z_file.getName());
				e_file.addAttribute("size", Long.toString(f_size));
				e_file.addAttribute("crc", Long.toString(z_file.getCrc()));
			}
			*/
			saveToCatalog(root);
		}
		
		is.close();
		zf.close();
		
		}
		catch (Exception e){
			System.out.println("Error in file "+file.getAbsolutePath());
			e.printStackTrace();
		}
	}
	
	public static void process_file(File file){
			process_xml(file);
	}
	
	public static void process_directory(String folder){
		File f = new File (folder);
		String[] dirList = f.list();
		int i;
		for (i=0;i<dirList.length;i++){
			File f1 = new File(folder+File.separator+dirList[i]);
			if (f1.isFile()){
				if (f1.getName().endsWith(".zip")&&!f1.getName().equalsIgnoreCase("catalog.zip")){
					process_file(f1);
				}
				
			}
			else{
				process_directory(folder+File.separator+dirList[i]);
			}
		}
		
		
		
	}
	
	public static void compressFile(String origin_file, String compressed_file){
		final int BUFFER = 2048;
		try{
			BufferedInputStream bis = null;
			FileOutputStream dest = new FileOutputStream(compressed_file);
			ZipOutputStream zos = new ZipOutputStream(new BufferedOutputStream(dest));
			byte data[]=new byte[BUFFER];
			File f = new File (origin_file);
			FileInputStream fis = new FileInputStream(f);
			bis = new BufferedInputStream(fis,BUFFER);
			ZipEntry ze=new ZipEntry(f.getName());
			zos.putNextEntry(ze);
			int len;
			while ((len=bis.read(data))>0){
				zos.write(data, 0, len);
			}
			zos.flush();
			zos.closeEntry();
			bis.close();
			zos.close();
			
		}
		catch (Exception e){
			e.printStackTrace();
		}
	}
	
	public static void show_usage(){
		System.out.println("Usage: java -jar index.jar [folder]");
	}
	
}
